跳到主要内容

灰度发布、强制更新、多通道更新策略怎么设计?

考察点​

  • agent 大规模分发的发布工程能力
  • 更新策略与服务端配合设计

参考答案​

1. 为什么需要灰度​

agent 常驻用户电脑,一次带 bug 的全量更新可能同时打挂几万在线设备——桌面端没有"快速回滚线上代码"的能力(用户不重启就一直在跑坏版本),所以灰度是桌面端发布的第一生命线。

2. 多通道(channel)设计​

// electron-updater 原生支持 channel
autoUpdater.channel = 'beta'; // 从 latest-beta.yml 读取更新信息
latest.yml → 稳定版(全量用户)
latest-beta.yml → 内测通道(内部员工 + 种子用户)
latest-alpha.yml → 每日构建(开发自测)

打包时指定通道:electron-builder --publish always -c.publish.channel=beta,会生成 latest-beta.yml。

用户侧:设置页提供"加入预览计划"开关,切换 channel 后立即 checkForUpdates。

3. 按用户分桶的灰度(百分比发布)​

channel 粒度太粗,精细化灰度需要服务端参与:

客户端请求: GET /update-check?uid=xxx&version=1.2.0&channel=stable
服务端逻辑:
1. 计算 bucket = hash(uid) % 100
2. 当前灰度规则: 1.3.0 放量 20%
3. bucket < 20 → 返回 1.3.0 的 latest.yml 内容
否则 → 返回 1.2.0 的 latest.yml 内容
// 客户端:用自定义 feed URL,把分桶信息带给服务端
autoUpdater.setFeedURL({
provider: 'generic',
url: `https://update.example.com/check?uid=${deviceId}&v=${app.getVersion()}`,
});

分桶关键点:

  • 用稳定设备 ID 做 hash,保证同一设备在放量扩大后仍在新版本组(单调性),避免"今天灰度命中、明天又不命中"的版本来回横跳
  • 灰度比例存服务端配置,随时调整、随时暂停(一键停止放量是必须有的能力)

4. 强制更新(最小支持版本)​

场景:发现严重安全漏洞/协议不兼容,老版本必须停用。

服务端返回的更新元数据扩展字段:
{
"version": "1.3.0",
"minSupportedVersion": "1.1.0", // 低于此版本强制更新
"forceUpdate": false
}

客户端逻辑:

autoUpdater.on('update-available', async (info) => {
const force = semver.lt(app.getVersion(), info.minSupportedVersion);

if (force) {
// 强制模式:弹不可关闭的提示,下载完成后必须重启
showForceUpdateDialog(); // 无"稍后"按钮
await autoUpdater.downloadUpdate();
autoUpdater.quitAndInstall();
} else {
// 常规模式:可跳过
showOptionalUpdateDialog();
}
});

注意:

  • 强制更新也要给用户保存工作的机会(倒计时 30 分钟或保存提示后重启)
  • "跳过此版本"功能:记录被跳过的版本号,该版本不再提示(但强制更新不受跳过影响)

5. 发布节奏与观测指标​

完整的发布流程:

Day 0: alpha → 内部验证核心链路
Day 1: beta → 种子用户(1-5%)
Day 3: 指标正常 → stable 灰度 10%
Day 5: → 50%
Day 7: → 100%

放量决策依赖的指标(更新上报体系):

  • 更新成功率:下载成功/安装成功占比,失败原因分布
  • 新版本崩溃率:crashReporter 数据按版本分组对比
  • 核心功能埋点:新版本关键链路成功率不劣化
  • 在线版本分布:灰度版本实际渗透速度

任何指标异常 → 服务端把灰度比例调回 0 → 已升级用户靠"下一个修复版本"覆盖(桌面端无法回滚,只能向前修复)。

6. 补充机制​

  • 降级通道:极端情况提供一个"回退安装包"下载入口(人工干预)
  • 版本公告:update-available 时展示 changelog(latest.yml 的 releaseNotes 字段)
  • 静默期:agent 执行关键任务中(如正在备份)推迟重启更新,任务完成后再 quitAndInstall

面试话术​

我的发布体系三层:channel 做人群分层(alpha/beta/stable),服务端按设备 ID hash 分桶做百分比灰度(保证单调性、可一键停止),minSupportedVersion 字段实现强制更新。放量节奏靠数据驱动:更新成功率、分版本崩溃率、核心埋点达标才继续扩。桌面端没法回滚,所以"能随时停"比"发得快"重要得多。

常见追问​

  • 用户常年不重启怎么办? 更新已下载但未安装的用户占比要监控;可策略性在闲置时提示重启,或强制更新场景兜底。
  • 灰度发现 bug,已中招用户怎么处理? 火速发修复版本并把灰度直接指到修复版(向前修复),同时支持侧准备话术。